<?php
namespace control;
use ReflectionClass;
use ReflectionException;

// 编码设置
class codeTemplateClass extends adIndexClass
{
	private const page  = 'codeTemplate';
	private const table = 'code_template';
	private const title = '编码设置';

	/*编码入口页*/
	public function home(): string
	{
		$all    = self::getPowerAll();
		//返回
		$rightHtml = $this->homeRight();
        $html =  componentClass::leftNav([
            'title'=>'单据类型',
            'all'=>$all,
            'click'=>" replaceRightDetail(this) ",
            'allTitle'=>'所有编码',
            'rightHtml'=>$rightHtml,
        ]);
		$html      .= <<<EOT
<script>
function replaceRightDetail(obj, cla = '{$this->get('cla')}') {
    let api, menuThree, two, one, id = $(obj).attr('data-id')
    id = id === 'all' ? '' : id
    if (id.length > 0) {
        let that = $(obj).parent('ul')
        menuThree = that.attr('pid');
        two = that.parent('ul').attr('pid');
        one = that.parent('ul').parent('ul').attr('pid');
        ulScal(obj, id)
    }
    $("#container-left li").removeClass('active');
    $(obj).addClass('active')
    api = root + 'control/adIndex.html?cla=' + cla + '&fun=homeRightJson'
    $.post(api, {
        menuOne:one,
        menuTwo: two,
        menuThree: menuThree,
        menuFour: id
    }, function (data) {
        $('#container-detail').html(data.html)
    }, "json");
}
</script>
EOT;
		//返回
		return $this->homeFun($html);
	}

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "单据类型" => text(array("name" => "name")),
                    "编码规则" => text(array("name" => "codeRule")),
                    "状态"   => select(["name" => 'state', 'option' => ['启用', '停用']])
                        . hidden(['name' => 'menuOne', 'value' => $this->post('menuOne')])
                        . hidden(['name' => 'menuTwo', 'value' => $this->post('menuTwo')])
                        . hidden(['name' => 'menuThree', 'value' => $this->post('menuThree')])
                        . hidden(['name' => 'menuFour', 'value' => $this->post('menuFour')])
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

	public function homeRight(): string
	{
        $html = $this->homeOptions(false);
        //控件
        $button    = "";
        $equal = [
            'menuOne'   => $this->post('menuOne'),
            'menuTwo'   => $this->post('menuTwo'),
            'menuThree' => $this->post('menuThree'),
            'menuFour' => $this->post('menuFour'),
        ];
        $equalJson = base64_encode(json_encode($equal, 320));
        if ($this->power(self::page, "edit") && $this->post('menuThree')) {
            $button .= "<span onclick=\"layer('" . $this->get('cla') . "', 'edit', {id:'" . suiji() . "', data: '$equalJson' })\" class='spanButton'>新增</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del', data: '$equalJson'})\">删除</span>\n";
        }
        if ($this->power(self::page, "state")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get['cla']}', 'operate', {'act': 'changeState', 'state': '启用'})\">启用</span>\n";
        }
        if ($this->power(self::page, "state")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get['cla']}', 'operate', {'act': 'changeState', 'state': '停用'})\">停用</span>\n";
        }
		return $this->search($html, layout: 'pop', toolButton: $button);
	}

	/**
	 * 左侧搜索框
	 *
	 * @return string
	 */
	public function getContainerLeftJson(): string
	{
		$json['html'] = self::getPowerAll();
		return json_encode($json, 320);
	}

	/**
	 * 获取数据
	 *
	 * @return array
	 */
	private static function receiveData(): array
	{
		global $powerAll;
		$result = [];
        foreach ($powerAll as $one => $oneArray) {
            $oneTemp = [];
            foreach ($oneArray as $two => $twoArray) {
                $twoTemp = [];
                foreach ($twoArray as $three => $threeArray) {
                    $threeTemp = [];
                    foreach ($threeArray as $four => $value) {
                        if (isset($value['name'])) {
                            $threeTemp[$four] = $value['name'];
                        }
                    }
                    if (!empty($threeTemp)) {
                        $twoTemp[$three] = $threeTemp;
                    }
                }
                if (!empty($twoTemp)) {
                    $oneTemp[$two] = $twoTemp;
                }
            }
            if (!empty($oneTemp)) {
                $result[$one] = $oneTemp;
            }
        }
		return $result;
	}

	public static function getPowerAll(array $local = [], string $pid = ''): string
	{
		$result = $local ?: self::receiveData();
		$style  = empty($pid) ? '' : ' class="child-node"';
		$temp   = "<ul $style $pid>";
		// 角标
		$arrow   = arrow;
		$lastone = lastone;
        $textcontent_ico = "<span class='textcontent_ico'></span>";
		foreach ($result as $key => $value) {
			// 判断下级是否存在
			$pid = "pid=$key";
			if (is_array($value)) {
				$temp .= "<li data-id='$key' onclick=\"ulScal(this, '$key')\">$arrow <span class='textcontent'>{$textcontent_ico}{$key}</span></li>";
				$temp .= self::getPowerAll($value, $pid);
			} else {
				$temp .= "<li data-id='$key' onclick=\"replaceRightDetail(this)\">$lastone <span class='textcontent'>{$textcontent_ico}{$value}</span></li>";
			}
		}
		$temp .= '</ul>';
		return $temp;
	}

	/**
	 * 异步加载
	 */
	public function homeRightJson(): string
	{
		$json['html'] = $this->homeRight();
		return json_encode($json, 320);
	}

	public function homeRightJsonSearch(): string
	{
		return $this->homeSearch();
	}

	/**
	 * 三级菜单名称
	 *
	 * @return string
	 */
	private function menuThreeName($array): string
	{
		return $this->powerAll[$array['menuOne']][$array['menuTwo']][$array['menuThree']]['name'];
	}

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'name'          => [
                        'name'  => "单据类型",
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'codeRule'  => [
                        'name'  => '编码规则',
                        'width' => 300,
                    ],
                    'split'         => [
                        'name'  => '段间分隔符',
                        'width' => 150,
                    ],
                    'text'          => [
                        'name'  => '备注',
                        'width' => 300,
                    ],
                    'state'          => [
                        'name'  => '状态',
                        'width' => 150,
                    ]
                ];
        }
        return $tr;
    }

	/*列表页-查询结果*/
	public function homeSearch(): bool|string
	{
		$equal = [
			'menuOne'   => $this->post('menuOne'),
			'menuTwo'   => $this->post('menuTwo'),
			'menuThree' => $this->post('menuThree'),
            'menuFour' => $this->post('menuFour'),
		];
		//获取查询结果
		$where = search([
			"like" => [
				"name"     => $this->post('name'),//单据类型
				"codeRule" => $this->post('codeRule'),//编码规则
			],
			'='    => $equal,
		]);
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'list, time',
            "sort" => $this->post('list_sort') ?: "asc",
            "array"   => array(),
        ));
		$page  = $this->page([
			"table" => self::table,
			"where" => $where,
			"order" => $orderBy['orderBy'],
		]);
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "id")
        );
		//获取记录
		foreach ($page['array'] as $array) {
			//列表控件
			$dominate = $this->dominate([
				"box"    => ["name" => "id", "value" => $array['id']],
				"edit"   => ["title" => "编辑编码", "click" => "layer('" . $this->get('cla') . "', 'edit', {id:'" . $array['id'] . "'})"],
				"detail" => ["title" => "编码详情", "click" => "newIframe('编码详情','" . root . "control/adIndex.html?cla=" . self::page . "&fun=detail&id=" . $array['id'] . "')"],
			]);
            $liButton[] = $dominate;
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
		}
		//控件
		$button    = "";
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
        ));
		//返回
		$json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'];
		return json_encode($json, 320);
	}

	/**
	 * 编辑页
	 *
	 * @return string
	 */
	public function edit(): string
	{
		$id     = $this->post('id') ? $this->post('id') : '';
		$obj    = $this->post('data') ?: '';
		$result = json_decode(base64_decode($obj), 320);
		//数据查询
		$info          = query(self::table, " id = '" . $id . "' ");
		$menuOne       = $info['menuOne'] ?: $result['menuOne'];
		$menuTwo       = $info['menuTwo'] ?: $result['menuTwo'];
		$menuThree     = $info['menuThree'] ?: $result['menuThree'];
        $menuFour = $info['menuFour'] ?: $result['menuFour'];
        $menuFourName = $this->powerAll[$menuOne][$menuTwo][$menuThree][$menuFour]['name'];
		$name          = $info['name'] ?: $menuFourName;
		//表单
		$html = $this->layerEdit(array(
			"table" => array(
				array(
					must . "单据类型：" => $name . hidden(["name" => "name", "value" => $name]),
				),
				array(
					must . "所属模块：" => $menuOne . ' - ' . $menuTwo . ' - ' . $menuThree.' - '.$menuFourName,
				),
				array(
					"备注：" => textarea(["name" => "text", "value" => $info['text']]).
					hidden(['name' => 'menuOne', 'value' => $menuOne])
					. hidden(['name' => 'menuTwo', 'value' => $menuTwo])
					. hidden(['name' => 'menuThree', 'value' => $menuThree])
                    . hidden(['name' => 'menuFour', 'value' => $menuFour]),
				),
			),
		));
		//返回
		return $this->layer(["title" => "编辑编码", "height" => 320, "html" => $html]);
	}

	/*编码详情页~基本信息-异步处理*/
	public function editEdit(): bool|string
	{
		$id = $this->post('id') ?: self::getId();
		//赋值
		$field      = [
			"name"      => $this->post('name'),
			"menuOne"   => $this->post('menuOne'),
			"menuTwo"   => $this->post('menuTwo'),
			"menuThree" => $this->post('menuThree'),
            "menuFour" => $this->post('menuFour'),
			"text"      => $this->post('text'),
		];
		$annotation = [
			"name"      => '单据类型',
			"menuOne"   => '一级菜单',
			"menuTwo"   => '二级菜单',
			"menuThree" => '三级菜单',
            "menuFour" => '四级级菜单',
			"text"      => '备注',
		];
		$rules      = [
			"name"      => 'required',
			"menuOne"   => 'required',
			"menuTwo"   => 'required',
			"menuThree" => 'required',
            "menuFour" => 'required',
		];
		// 校验是否符合规则
		$vt     = new \verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
			goto resp;
		}
		$info = query(self::table, " id = '" . $this->post('id') . "' ");
		//判断
		if (!$this->power(self::page, "edit")) {
			$json['warn'] = "你没有编辑打印编码的权限";
		} elseif (empty($info['id'])) {
			// 该模块已有一个已启用编码
			if (sqlNum(self::table, " menuFour = '$field[menuFour]' and state='启用' and id <> '" . $id . "' ") > 0) {
				$field['state'] = '停用';
			} else {
				$field['state'] = '启用';
			}
			$field        = array_merge($field, [
				"id"   => $id,
				'stid' => self::$stid,
			]);
			$json['warn'] = static::insert(["table" => self::table, "field" => $field]);
		} else {
			$json['warn'] = static::update(["table" => self::table, "field" => $field, "where" => "id = '" . $id . "'"]);
		}
		if (in_array($json['warn'], ["新增成功", "更新成功"])) {
			//添加日志
			$type = mb_substr($json['warn'], 0, 2, 'utf-8');
			$text = $this->control['name'] . $type . "了一个打印编码：" . $field['name'];
			$this->logText(["type" => "role", "text" => $text]);
			//提示
			$_SESSION['warn'] = $json['warn'];
			$json['warn']     = 2;
		}
		//返回
		resp:
		return json_encode($json, 320);
	}

	/*详情页*/
	public function detail(): string
	{
		$id   = $this->get('id');
		$info = query(self::table, " id = '{$this->get('id')}'");
		if (empty($info['id'])) {
			$html = '未找到此' . self::title;
		} else {
			//菜单
			$data = array(
				"id"    => $info['id'],
				"title" => self::title . '详情',
			);

			$button   = [];
			if ($this->power(self::page, "edit")) {
				//按钮
				$button[] = [
					"name" => "删除",
					"type" => "弹出层",
					"cla"  => $this->get('cla'),
					"fun"  => "operate",
					"post" => ["act" => 'del', "id" => $info['id']],
				];
				//按钮
				/*$button[] = [
					"name" => "编辑",
					"type" => "顶部页卡",
					"title" => "编辑用户",
					"url" => $this->root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=edit&id=' . $info['id'],
				];*/
				$button[] = [
					"name"  => "保存",
					"type"  => "点击事件",
					"fun"   => "subForm('" . self::page . "DetailForm,addDetailForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=detailEdit')",
					'style' => 'li-btn-blue-bg',
				];
			}
			$sectionText = "";
			$lastClass   = "";
			$body        = json_decode($info['body'], true);
            $tip = componentClass::tipComponent('设置为是时，后面的编码段有流水号时，流水号则会加上此段进行递增', Symbol: '?', label: 'span');
			if (is_array($body) && count($body) > 0) {
				require_once "codeTemplateData.php";
				foreach ($body as $k => $value) {
					$select = select(["name" => "type[]", 'class' => 'text width200', 'title' => '请选择', 'option' => ['常量', '日期', '业务字段', '流水号'], "value" => $value['type'], "change" => "getSectionMx"]);
					switch ($value['type']) {
						case '常量':
							$setValue  = "<span class='section-title'>" . must . "设置值：</span><span>" . text(['name' => "setValue[]", 'class' => 'text', 'value' => $value['setValue']]) . "</span>";
							$setValue2 = "<span class='section-title'></span><span>" . hidden(['name' => 'setValue2[]', 'value' => '']) . "</span>";
							break;
						case '日期':
							$setValue  = "<span class='section-title'>" . must . "日期格式：</span><span>" . select(["name" => "setValue[]", 'class' => 'text width200', 'title' => '请选择', 'option' => ['yyyyMMdd', 'yyMMdd'], "value" => $value['setValue']]) . "</span>";
							$setValue2 = "<span class='section-title'>流水号依据：</span><span>" . self::uiSwitch(['name' => 'setValue2[]', 'value' => $value['setValue2']]) . "</span>".$tip;
							break;
						case '业务字段':
							$option    = isset($codeData[$info['menuOne']][$info['name']]) ? $codeData[$info['menuOne']][$info['name']] : [];
							$setValue  = "<span class='section-title'>" . must . "字段名：</span><span>" . select(["name" => "setValue[]", 'class' => 'text width200', 'title' => '请选择', 'option' => $option, "value" => $value['setValue']]) . "</span>";
							$setValue2 = "<span class='section-title'>流水号依据：</span><span>" . self::uiSwitch(['name' => 'setValue2[]', 'value' => $value['setValue2']]) . "</span>".$tip;
							break;
						case '流水号':
							$setValue  = "<span class='section-title'>" . must . "长度：</span><span>" . text(['name' => "setValue[]", 'type' => 'number', 'class' => 'text', 'value' => $value['setValue']]) . "</span>";
							$setValue2 = "<span class='section-title'>" . must . "起始值：</span><span>" . text(['name' => "setValue2[]", 'type' => 'number', 'class' => 'text', 'value' => $value['setValue2']]) . "</span>";
							break;
						default:
							$setValue  = '';
							$setValue2 = '';
					}
					if ($k == count($body) - 1) $lastClass = 'last';
					$sectionText .= "<div class='section-sub $lastClass'>
                        <p class='type'><span class='section-title'>" . must . "编码一段：</span><span>" . $select . "</span></p>
                        <p class='set-value'>$setValue</p>
                        <p class='set-value-2'>$setValue2</p>
                    </div>";
				}
			} else {
				$sectionText .= $this->combinationSection(4);
			}
			$codeRule = $info['codeRule'] ?: '常量-日期-业务字段-流水号';
			//生成表单
            $data['button'] = $this->tableShowButton($button);
            $body           = $this->edit4([
                '基本信息' => [
                    [
                        "单据类型："          => $info['name'],
                        must . "编码分段："   => select(["name" => "sectionNum", 'class' => 'text', 'title' => '请选择', 'option' => [1, 2, 3, 4, 5, 6], "value" => $info['sectionNum'] ?: 4, "change" => "getSection"]),
                        must . "段间分隔符：" => select(["name" => "split", 'class' => 'text', 'title' => '请选择', 'option' => array_merge(['无'], explode('，', para('splitCharOption'))), "value" => $info['split'] ?: '-', "change" => ""]),
                        "应用规则：" => select(["name" => "rule", 'class' => 'text width200', 'title' => '请选择', 'option' => ['自动新增不允许修改'], "value" => $info['rule'] ?: '自动新增不允许修改', "change" => ""]),
                    ],
                ]
            ]);
			$data['html'] = $this->pageEdit([
					"html"  => $body,
					'hidden' => hidden(['name' => 'id', 'value' => $id]),
				]) .
                "
                <div class='edit4 codeDiv'>
                    <p>编码设置</p>
                    <form name='addDetailForm'>
                        <div class='rule'>
                                <p>" . $this->templateCode($info) . "</p>
                                <p>$codeRule</p>
                        </div>
                        <div id='sectionText'>$sectionText</div>
                    </form>
                </div>";
			$html         = $this->tab($data) . $this->style() . $this->js();
		}
		//返回
		return $html;
	}

    public function style()
    {
        return <<<efo
<style>
        .rule{padding: 10px 0;}
        .rule p{text-align: center;}
        #sectionText{background-color: #eee;display: flex;justify-content: space-between;padding: 2px 0;}
        .section-title{display: inline-block;width: 90px;text-align: left;}
        .section-sub p{margin-bottom: 25px;}
        .section-sub{padding: 30px 25px;height: 350px;width: 100%;background-color: white;margin-right: 2px;}
        .last{margin-right: 0!important;}
        .pageDiv{padding: 0!important;}
        .layerList{background-color: white;}
        form[name="codeTemplateDetailForm"] { background-color: white;padding-bottom: 5px;margin-bottom: 10px;}
        #sectionText select {height: 30px!important;}
        /* 开关按钮 */
          .btn-on{
            width: 60px;
            height: 25px;
            margin: 0 3px!important;
            border-radius: 25px;
            font-size: 14px;
            display: inline-block;
            vertical-align: middle;
          }
          .btn-on{
            cursor: pointer;
            position: relative;
            border: 1px solid white;
            background-color: #629afd;
          }
          .btn-on-circle{
            position: absolute;
            width: 15px;
            height: 15px;
            top: 5px;
            left: 5px;
            background-color: rgb(255, 255, 255);
            border-radius: 50%;
            box-shadow: 0 0 2px white;
            transition: all .5s;
          }
          .btn-on-text{
            position: absolute;
            right: 10px;
            line-height: 25px;
            color: white;
            transition: all .5s;
          }
</style>
efo;
    }

	/** 默认编码
	 *
	 * @param $query
	 * @return string
	 */
	public function templateCode($query): string
	{
		$code = "";
		if (!empty($query['id'])) {
			$body = json_decode($query['body'], true);
			foreach ((array)$body as $k => $val) {
				switch ($val['type']) {
					case '常量':
						$code .= $val['setValue'];
						break;
					case '日期':
						$date = date('Ymd');
						if ($val['setValue'] == 'yyMMdd') {
							$date = date('ymd');
						}
						$code .= $date;
						break;
					case '业务字段':
						require_once "codeTemplateData.php";
						$text = $codeData[$query['menuOne']][$query['name']][$val['setValue']] ?? '字段名';
						$code .= $text;
						break;
					case '流水号':
						$length = $val['setValue']; //填充位长度
						$code   .= str_pad($val['setValue2'], $length, '0', STR_PAD_LEFT);
						break;
					default:
				}
				if ($k != count($body) - 1) {
					$code .= $query['split'] == '无' ? '' : $query['split'];
				}
			}
		}
		return $code;
	}

	/** 根据编码规则生成编码
	 *
	 * @param string $page
	 * @param array  $data
	 * @param array  $field
	 * @return string
	 */
	public static function generateCode(string $page, array $data, array $field): string
	{
		$query          = query(self::table, " menuFour = '$page' and state = '启用' ");
		$query['split'] = $query['split'] == '无' ? '' : $query['split'];

		$code           = "";
		$prefix         = "";
		if (!empty($query['id'])) {
			$body = json_decode($query['body'], true);
			foreach ((array)$body as $k => $val) {
				$splicing = true; //拼接编码段标识
				switch ($val['type']) {
					case '常量':
						$code   .= $val['setValue'];
						$prefix .= $val['setValue'] . $query['split'] . '%';
						break;
					case '日期':
						$date = date('Ymd');
						if ($val['setValue'] == 'yyMMdd') {
							$date = date('ymd');
						}
						$code .= $date;
						if ($val['setValue2'] == 1) {
							$prefix .= $date . $query['split'] . '%';
						}
						break;
					case '业务字段':
						$wrod = $field[$val['setValue']] ?? '';
						if ($wrod) {
							$pinyin = strtoupper(PYClass::encode($wrod));
							$code   .= $pinyin;
							if ($val['setValue2'] == 1) {
								$prefix .= $pinyin . $query['split'] . '%';
							}
						} else {
							$splicing = false;
						}
						break;
					case '流水号':
						$table   = $data['table'] ?? 'user';
						$field   = $data['field'] ?? 'orderNo';
						$where   = $data['where'] ?? '';
						$index   = $data['index'] ?? 1;
						$length  = $val['setValue']; //填充位长度
						$default = str_pad($val['setValue2'], $length, '0', STR_PAD_LEFT);
						$res     = query($table, " `$field` LIKE '$prefix' $where  ORDER BY $field DESC ");
						if (!isset($res[$field]) || !$res[$field]) {
							$code .= $default;
						} else {
							//(int)$temp = str_replace($prefix, '', $res[$field]);
							(int)$temp = substr($res[$field], -1 * $length);
							$code .= (str_pad((intval($temp) + $index), $length, '0', STR_PAD_LEFT));
						}
						break;
					default:
				}
				if ($k != count($body) - 1 && $splicing) {
					$code .= $query['split'];
				}
			}
		}
		if (empty($code)) {

			$code = self::generateNo($data);

		}

		return $code;
	}

	public function js()
	{
		return <<<efo
<script>
        //获取分段内容
         function getSection(e){
             $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getSection',{num:e.value},function (res){
                 if(res.warn === 2){
                    $("#sectionText").html(res.data);
                 }else{
                     warn(res.warn,'error')
                 }
             },'json');
         }
         function getSectionMx(e){
             let par = $(e).parents('.section-sub')
             let id = $("[name='id']").val()
             $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getSectionMx',{type:e.value,id:id},function (res){
                 if(res.warn === 2){
                    par.find('.set-value').html(res.setValue);
                    par.find('.set-value-2').html(res.setValue2);
                 }else{
                     warn(res.warn,'error')
                 }
             },'json');
         }
</script>
efo;
	}

	/**单选切换按钮
	 *
	 * @param array $data
	 * @return string
	 */
	public static function uiSwitch(array $data): string
	{
		$id             = suiji();
		$data['value']  = $data['value'] ?: 0;
		$hidden         = hidden(['name' => $data['name'], 'value' => $data['value']]);
		$btnOn          = $data['value'] == 0 ? 'background-color: #ccc;' : '';
		$btnOnCircle    = $data['value'] == 0 ? 'left: 40px;background-color: #888;box-shadow: 0 0 10px #888;' : '';
		$btnOnTextStyle = $data['value'] == 0 ? 'right: 30px;color: #888;' : '';
		$btnOnText      = $data['value'] == 0 ? '否' : '是';
		return <<<efo
        <!-- 开关按钮 -->
        <span id="$id" class="btn-on" style="$btnOn" onclick="on_off('$id')">
          <!-- 圆点 -->
          <span class="btn-on-circle" style="$btnOnCircle"></span>
          <!-- 文字 -->
          <span class="btn-on-text" style="$btnOnTextStyle">$btnOnText</span>
          $hidden
        </span>
        <script>
          function on_off(id){
            var par = $('#'+id)
            var btn = par;
            var circle = par.find('.btn-on-circle');
            var text = par.find('.btn-on-text');
            var value = par.find('input').val()
            if(Number(value) === 1){
                btn.attr('style',"background-color: #ccc;")
                circle.attr('style',"left: 40px;background-color: #888;box-shadow: 0 0 10px #888;")
                text.attr('style',"right: 30px;color: #888;")
                text.text('否')
                par.find('input').val('0')
            } else {
                btn.attr('style',"")
                circle.attr('style',"")
                text.attr('style',"")
                text.text('是')
                par.find('input').val('1')
            }
          }
          
        </script>
efo;
	}

	/**
	 * 分段选项切换
	 *
	 * @return string
	 */
	public function getSectionMx()
	{
		$type = $this->post('type');
		$info = query(self::table, " id = '" . $this->post('id') . "' ");
		if (!empty($type) && $info['id']) {
			$json['warn'] = 2;
			switch ($type) {
				case '常量':
					$setValue  = "<span class='section-title'>" . must . "设置值：</span><span>" . text(['name' => "setValue[]", 'class' => 'text', 'value' => '']) . "</span>";
					$setValue2 = "<span class='section-title'></span><span>" . hidden(['name' => 'setValue2[]', 'value' => '']) . "</span>";
					break;
				case '日期':
					$setValue  = "<span class='section-title'>" . must . "日期格式：</span><span>" . select(["name" => "setValue[]", 'class' => 'text width200', 'title' => '请选择', 'option' => ['yyyyMMdd', 'yyMMdd'], "value" => '']) . "</span>";
					$setValue2 = "<span class='section-title'>流水号依据：</span><span>" . self::uiSwitch(['name' => 'setValue2[]', 'value' => '']) . "</span>";
					break;
				case '业务字段':
					$codeData = [];
					require_once "codeTemplateData.php";
					$option    = $codeData[$info['menuOne']][$info['name']] ?? [];
					$setValue  = "<span class='section-title'>" . must . "字段名：</span><span>" . select(["name" => "setValue[]", 'class' => 'text width200', 'title' => '请选择', 'option' => $option, "value" => '']) . "</span>";
					$setValue2 = "<span class='section-title'>流水号依据：</span><span>" . self::uiSwitch(['name' => 'setValue2[]', 'value' => '']) . "</span>";
					break;
				case '流水号':
					$setValue  = "<span class='section-title'>" . must . "长度：</span><span>" . text(['name' => "setValue[]", 'type' => 'number', 'class' => 'text', 'value' => '']) . "</span>";
					$setValue2 = "<span class='section-title'>" . must . "起始值：</span><span>" . text(['name' => "setValue2[]", 'type' => 'number', 'class' => 'text', 'value' => '']) . "</span>";
					break;
				default:
					$setValue  = '';
					$setValue2 = '';
			}
			$json['setValue']  = $setValue;
			$json['setValue2'] = $setValue2;
		} elseif (empty($type)) {
			$json['warn'] = '请选择编码类型';
		} elseif (empty($info['id'])) {
			$json['warn'] = '未找到编码规则';
		}
		return json_encode($json, 320);
	}

	/**
	 * 获取分段内容
	 *
	 * @return string
	 */
	public function getSection()
	{
		$num = $this->post('num');
		if (!empty($num)) {
			$json['warn'] = 2;
			$json['data'] = $this->combinationSection($num);
		} else {
			$json['warn'] = '请选择编码分段';
		}
		return json_encode($json, 320);
	}

	/** 根据分段数组合分段内容
	 *
	 * @param int $num
	 * @return string
	 */
	public function combinationSection(int $num): string
	{
		$html      = "";
		$lastClass = '';
		$select    = select(["name" => "type[]", 'class' => 'text width200', 'title' => '请选择', 'option' => ['常量', '日期', '业务字段', '流水号'], "value" => '', "change" => "getSectionMx"]);
		for ($i = 0; $i < $num; $i++) {
			if ($i == $num - 1) $lastClass = 'last';
			$html .= "<div class='section-sub $lastClass'>
                        <p class='type'><span class='section-title'>" . must . "编码一段：</span><span>" . $select . "</span></p>
                        <p class='set-value'></p>
                        <p class='set-value-2'></p>
                    </div>";
		}
		return $html;
	}

	/*编码详情页~基本信息-异步处理*/
	public function detailEdit(): bool|string
	{
		$id = $this->post('id');
		//赋值
		$field      = [
			"sectionNum" => $this->post('sectionNum'),
			"split"      => $this->post('split'),
			"rule"       => $this->post('rule'),
		];
		$annotation = [
			"sectionNum" => '编码分段',
			"split"      => '段间分隔符',
			"rule"       => '应用规则',
		];
		$rules      = [
			"sectionNum" => 'required',
			"split"      => 'required',
		];
		// 校验是否符合规则
		$vt     = new \verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
			goto resp;
		}
		$body     = [];
		$codeRule = [];
		foreach ((array)$this->post('type') as $k => $v) {
			if (empty($v)) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，未选择编码段类型";
				goto resp;
			} elseif ($v == '常量' && empty($this->post('setValue')[$k])) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，请输入设置值";
				goto resp;
			} elseif ($v == '日期' && empty($this->post('setValue')[$k])) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，请选择日期格式";
				goto resp;
			} elseif ($v == '业务字段' && empty($this->post('setValue')[$k])) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，请输入字段名";
				goto resp;
			} elseif ($v == '流水号' && $k + 1 != count($this->post('type'))) {
				$json['warn'] = "流水号只能设置在编码最后一段";
				goto resp;
			} elseif ($v == '流水号' && empty($this->post('setValue')[$k])) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，请输入长度";
				goto resp;
			} elseif ($v == '流水号' && $this->post('setValue')[$k] > 8) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，流水号长度不能超过8";
				goto resp;
			} elseif ($v == '流水号' && empty($this->post('setValue2')[$k])) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，请输入起始值";
				goto resp;
			} elseif ($v == '流水号' && strlen($this->post('setValue2')[$k]) > $this->post('setValue')[$k]) {
				$json['warn'] = "第" . ($k + 1) . "个编码段，起始值长度不能超过流水号长度";
				goto resp;
			}
			$body[]     = [
				'type'      => $v,
				'setValue'  => $this->post('setValue')[$k],
				'setValue2' => $this->post('setValue2')[$k],
			];
			$codeRule[] = $v;
		}
		$info = query(self::table, " id = '" . $this->post('id') . "' ");
		//判断
		if (!$this->power(self::page, "edit")) {
			$json['warn'] = "你没有编辑打印编码的权限";
		} elseif (empty($info['id'])) {
			$json['warn'] = "未找到该编码规则";
		} else {
			$field['codeRule'] = implode($field['split'] == '无' ? '' : $field['split'], $codeRule);
			$field['body']     = json_encode($body, 320);
			$json['warn']      = static::update(["table" => self::table, "field" => $field, "where" => "id = '" . $id . "'"]);
		}
		if (in_array($json['warn'], ["新增成功", "更新成功"])) {
			//添加日志
			$type = mb_substr($json['warn'], 0, 2, 'utf-8');
			$text = $this->control['name'] . $type . "了一个编码规则：" . $info['name'];
			$this->logText(["type" => self::page, "text" => $text]);
			//提示
			$_SESSION['warn'] = $json['warn'];
			$json['warn']     = 2;
		}
		//返回
		resp:
		return json_encode($json, 320);
	}

	/**
	 * 复制编码
	 *
	 * @return string
	 */
	public function copy()
	{
		$info = query(self::table, " id = '" . $this->post('id') . "' ");
		//判断
		if (!$this->power(self::page, "edit")) {
			$json['warn'] = "你没有编辑打印编码的权限";
		} elseif (empty($info['id'])) {
			$json['warn'] = "参数错误";
		} else {
			unset($info['id'], $info['time'], $info['updateTime']);
			$field        = array_merge($info, [
				"id"    => self::getId(),
				"state" => '停用',
				'stid'  => self::$stid,
			]);
			$json['warn'] = static::insert(["table" => self::table, "field" => $field,]);
		}
		if (in_array($json['warn'], ["新增成功", "更新成功"])) {
			//添加日志
			$type = mb_substr($json['warn'], 0, 2, 'utf-8');
			$text = $this->control['name'] . $type . "了一个打印编码：" . $info['name'];
			$this->logText(["type" => "role", "text" => $text]);
			//提示
			$_SESSION['warn'] = $json['warn'];
			$json['warn']     = 2;
		}
		//返回
		resp:
		return json_encode($json, 320);
	}

	/**
	 * 更新编码
	 *
	 * @return string
	 */
	public function upbody(): string
	{
		$id = $this->post('id') ?: self::getId();
		//赋值
		$field      = [
			"tplBody" => $this->post('tplBody'),
		];
		$annotation = [
			"tplBody" => '编码内容',
		];
		$rules      = [
			"tplBody" => 'required',
		];
		// 校验是否符合规则
		$vt     = new \verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
			goto resp;
		}
		$info = query(self::table, " id = '" . $this->post('id') . "' ");
		//判断
		if (!$this->power(self::page, "edit")) {
			$json['warn'] = "你没有编辑打印编码的权限";
		} /*elseif ($info['state'] === '启用') {
			$json['warn'] = "编码为启用状态，无法修改";
		} */ else {
			$json['warn'] = static::update(["table" => self::table, "field" => $field, "where" => "id = '" . $id . "'"]);
		}
		if (in_array($json['warn'], ["新增成功", "更新成功"])) {
			//添加日志
			$type = mb_substr($json['warn'], 0, 2, 'utf-8');
			$text = $this->control['name'] . $type . "了一个打印编码：" . $info['name'];
			$this->logText(["type" => "role", "text" => $text]);
			//提示
			$_SESSION['warn'] = $json['warn'];
			$json['warn']     = 2;
		}
		//返回
		resp:
		return json_encode($json, 320);
	}

	// 操作中转
	public function operate(): bool|string
	{
		$act    = $this->post('act') ?? '';
		$pwd    = $word = false; // 需要密码
		$form   = $power = '';
		$append = [];
		switch ($act) {
			case 'changeState':
				$act      = 'state';
				$msg      = self::title . '修改状态';
				$title    = '是否确认修改选中的编码设置为' . $this->post('state') . '状态';
				$function = 'changeState';
				$form     = self::page . 'OperateForm, listForm';
				if ($this->post('state')) {
					$append = [
						0 => hidden(['name' => 'state', 'value' => $this->post('state')]),
					];
				}
				$power = '';
				$word  = true;
				break;
			default:
				$act      = 'del';
				$msg      = '删除' . self::title;
				$title    = self::page . 'Delete';
				$function = 'delete';
				$form     = self::page . 'OperateForm, listForm';
				$power    = '';
				break;
		}
		if (!$this->power(self::page, $act)) {
			$_SESSION['warn'] = '你还没有' . $msg . '的权限';
			$json             = [
				'warn' => 2,
				'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
			];
		} else {
			return $this->confirm([
				'title'    => $title,
				'function' => $function,
				'form'     => $form,
				'power'    => $power,
				'pwd'      => $pwd,
				'append'   => $append,
				'word'     => $word,
			]);
		}

		resp:
		return json_encode($json, 320);
	}

	/**
	 * 删除
	 *
	 * @return bool|string
	 */
	public function delete(): bool|string
	{
		$array = $this->post('listId') ?? $this->post('id');
		if (!$this->power(self::page, "del")) {
			$json['warn'] = "你没有删除的权限";
		} elseif (empty($array)) {
			$json['warn'] = "你一个数据都没有选择呢";
		} else {
			$text  = "";
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			foreach ($array as $id) {
				$info = query(self::table, " id = '$id' ");
				if ($info['state'] != '停用') {
					$warn = "删除失败：不是停用状态";
				} else {
					//最后删除基本参数
					delete(array("table" => self::table, "where" => " id = '$id' "));
					//返回
					$warn = "删除成功";
					$x++;
				}
				$text .= self::title . "ID【" . $info['id'] . "】,单据类型【{$info['name']}】" . $warn . "。<br>";
			}
			//添加日志
			$text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
			$this->logText(array("type" => self::page, "text" => $text));
			$_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
			$json['warn']     = 2;
			$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
		}
		return json_encode($json, 320);
	}


	/**
	 * 修改状态
	 *
	 * @return bool|string
	 */
	public function changeState(): bool|string
	{
		$array = $this->post('listId') ?? $this->post('id');
		$state = $this->post('state') ?: '停用';
		$act   = 'state';
		$json  = [];
		if (!$this->power(self::page, $act)) {
			$json['warn'] = "你没有此权限的权限";
		} elseif (empty($array)) {
			$json['warn'] = "你一条记录都没有选择呢";
		} else {
			$text  = '';
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			// 修改field
			$fieldKey = 'state';
			foreach ($array as $id) {
				$where = " id = '$id' ";
				$info  = query(self::table, $where);
				if (static::isNull($info['id'])) {
					continue;
				}
				$fieldVlaue = ($state === '停用') ? '停用' : '启用';
				// 停用前判断
				if ($fieldVlaue == '停用') {
					if (sqlNum(self::table, " menuThree = '$info[menuThree]' and state='启用' ") == 1) {
						//$menuThreeName = $this->menuThreeName($info);
						$text .= "【{$info['name']}】仅有一条编码设置，无法停用<br>";
						continue;
					}
				} else {
					//	判断启用
					static::update([
						"table" => self::table,
						'field' => [
							$fieldKey => '停用',
						],
						"where" => " id <> '$id' and menuThree = '$info[menuThree]' ",
					]);
				}

				// 修改状态
				static::update([
					"table" => self::table,
					'field' => [
						$fieldKey => $fieldVlaue,
					],
					"where" => $where,
				]);
				//添加记录
				$text .= "管理员{$this->control['name']}修改了一条" . self::title . "：ID【{$id}】<br>";
				$x++;
			}
			// 写入日志
			$this->logText(["type" => self::page, "text" => $text]);
			$_SESSION['warn'] = "修改了{$x}条" . self::title;
			$json['warn']     = 2;
			$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
		}
		resp:
		return json_encode($json, 320);
	}

	/**
	 * 获取字段类型
	 *
	 * @param $type
	 * @return string
	 */
	private static function getFieldType($type): string
	{
		if (str_contains($type, 'text')) {
			return 'longText';
		} elseif (str_contains($type, 'url') || str_contains($type, 'src')) {
			return 'image';
		} else {
			return 'text';
		}
	}

	/**
	 * 显示字段
	 *
	 * @param $sql
	 * @return array
	 */
	private static function showFiled($sql): array
	{
		$result = sqlFind($sql);
		$items  = [];
		foreach ($result as $value) {
			$items[] = [
				'title' => $value['Comment'],
				'field' => $value['Field'],
				'type'  => self::getFieldType($value['Type']),
			];
		}
		return $items;
	}

	/**
	 * 获取表名
	 *
	 * @string cla 类名
	 * @return array
	 * @throws ReflectionException
	 */
	private static function getTable(string $cla): array
	{
		$tables = [];
		$array  = ['table', 'tableMx'];
		foreach ($array as $item) {
			$table = (new ReflectionClass($cla))->getConstant($item);
			if ($table !== false) {
				$tables[$item] = $table;
			}
		}
		return $tables;
	}


}
